package me.zhengjie.service.impl;

import lombok.RequiredArgsConstructor;
import me.zhengjie.pojo.sqlServer.PPStorage;
import me.zhengjie.ppService.PpPalletService;
import me.zhengjie.repository.PPInventoryRepository;
import me.zhengjie.repository.PPStorageRepository;
import me.zhengjie.repository.PpPalletRepository;
import me.zhengjie.service.PPStorageService;
import me.zhengjie.service.PPTimeConfigService;
import me.zhengjie.service.dto.PPStorageDto;
import me.zhengjie.service.dto.PPStorageQueryCriteria;
import me.zhengjie.service.mapper.PPStorageMapper;
import me.zhengjie.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
@RequiredArgsConstructor
public class PPStorageServiceImpl  implements PPStorageService {

    private final PPStorageRepository ppStorageRepository;
    private final PPStorageMapper ppStorageMapper;
    private final PPInventoryRepository ppInventoryRepository;
    private final PPTimeConfigService  ppTimeConfigService ;


    private static final Logger ppLog = LoggerFactory.getLogger("pp");
    private final PpPalletRepository ppPalletRepository;

    @Override
    public PageResult<PPStorageDto> queryAll(PPStorageQueryCriteria criteria, Pageable pageable){
        Page<PPStorage> page = ppStorageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(ppStorageMapper::toDto));
    }

    @Override
    public List<PPStorageDto> queryAll(PPStorageQueryCriteria criteria){
        return ppStorageMapper.toDto(ppStorageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public PPStorageDto findById(Integer id) {
        PPStorage ppStorage = ppStorageRepository.findById(id).orElseGet(PPStorage::new);
        ValidationUtil.isNull(ppStorage.getId(),"PPStorage","id",id);
        return ppStorageMapper.toDto(ppStorage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(PPStorage resources) {
        ppStorageRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PPStorage resources) {
        PPStorage ppStorage = ppStorageRepository.findById(resources.getId()).orElseGet(PPStorage::new);
        ValidationUtil.isNull( ppStorage.getId(),"PPStorage","id",resources.getId());
        ppStorage.copy(resources);
        ppStorageRepository.save(ppStorage);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            ppStorageRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<PPStorageDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (PPStorageDto ppStorage : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("逻辑地址类型", ppStorage.getLogicalAddressType());
            map.put("仓库编码", ppStorage.getWarehouseCode());
            map.put("载盘编码",  ppStorage.getPalletCode());
            map.put("库区编号", ppStorage.getZoneCode());
            map.put("储位编码", ppStorage.getStorageCode());
            map.put("巷道号", ppStorage.getAisle());
            map.put("层号", ppStorage.getLayer());
            map.put("排号", ppStorage.getRow());
            map.put("列号", ppStorage.getColumn());
            map.put("是否有货", ppStorage.getLocationInventoryStatus());
            map.put("是否启用", ppStorage.getStatus());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<PPStorage> findSuitableStorage() {
        //获取所有可用储位，并过滤掉有货和有载盘的储位
        List<PPStorage> storages = ppStorageRepository.findSuitabkePPStorage().stream()
                .filter(storage -> StringUtils.isBlank(storage.getPalletCode())).collect(Collectors.toList());

        return storages;
    }

    @Override
    public void updateStorage(PPStorage storage) {

        ppStorageRepository.save(storage);

    }

    @Override
    public List<PPStorage> findStorageByWareHouseArea(String area) {
        return null;
    }

    @Override
    public List<PPStorage> findStoragesByRowAndWareHouseAreaAndLayerOrderByColumn(int row, String area, int layer) {
        return null;
    }

    @Override
    public String findStorageCodeById(Integer Id) {
        return ppStorageRepository.findStorageCodeById(Id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void lockStorage(String storageCode) {

        ppStorageRepository.lockStorage(storageCode);


    }

    @Override
    public List<PPStorage> findAllOpenStorages() {
        return ppStorageRepository.findAllOpenStorages();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cleanStorage(String storageCode) {
        ppStorageRepository.cleanStorage(storageCode);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int openStorage(String storageCode) {
       return ppStorageRepository.openStorages(storageCode);
    }

    @Override
    public PPStorage findStorageByStorageCode(String storageCode) {
       return ppStorageRepository.findStorageByStorageCode(storageCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int finishInBound(String palletCode, String storageCode) {
        return  ppStorageRepository.finishInBound(palletCode,storageCode);
    }


    //空载盘入库
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishInBoundNullPallet(String palletCode, String storageCode) {
        ppStorageRepository.finishInBoundNullPallet(palletCode,storageCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeStorageStatusById(Integer status, Integer storageId) {
        return  ppStorageRepository.changeStorageStatusById(status,storageId);
    }

    @Override
    public PPStorage findPPStorageByPalletCode(String palletCode) {
        return ppStorageRepository.findPPStorageByPalletCode(palletCode);
    }

    @Override
    public void savePPStorage(List<PPStorage> fromExcel) {
        for (PPStorage storage : fromExcel) {
            //先查找有没有该库存，有就进行更新没有就进行新增
            if( ppStorageRepository.findPPStorageByStorageCode(storage.getStorageCode()) != null) {
                int oldPPStorageId = ppStorageRepository.findPPStorageByStorageCode(storage.getStorageCode()).getId();
                storage.setId(oldPPStorageId);
                ppStorageRepository.save(storage);
            }else {
                ppStorageRepository.save(storage);
            }
        }
//        ppStorageRepository.saveAll(fromExcel);
    }
}
